home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / VMSUNIX.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  9KB  |  410 lines

  1. /*    SCCS Id: @(#)vmsunix.c    3.0    88/04/13
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /* This file collects some Unix dependencies; pager.c contains some more */
  6.  
  7. /*
  8.  * The time is used for:
  9.  *    - seed for rand()
  10.  *    - year on tombstone and yymmdd in record file
  11.  *    - phase of the moon (various monsters react to NEW_MOON or FULL_MOON)
  12.  *    - night and midnight (the undead are dangerous at midnight)
  13.  *    - determination of what files are "very old"
  14.  */
  15.  
  16. #include "hack.h"
  17.  
  18. #include <rms.h>
  19. #include <jpidef.h>
  20. #include <ssdef.h>
  21. #include <errno.h>
  22. #include <signal.h>
  23. #undef off_t
  24. #ifndef VAXC
  25. #include <sys/stat.h>
  26. #else   VAXC
  27. #include <stat.h>
  28. #endif  VAXC
  29. #include <ctype.h>
  30. #ifdef no_c$$translate
  31. #include <errno.h>
  32. #define C$$TRANSLATE(status) (errno = EVMSERR,  vaxc$errno = (status))
  33. #else   /* must link with vaxcrtl object library (/lib or /incl=c$$translate) */
  34. extern FDECL(C$$TRANSLATE, (unsigned long));
  35. #endif
  36. extern unsigned long SYS$PARSE(), SYS$SEARCH(), SYS$ENTER(), SYS$REMOVE();
  37. extern unsigned long SYS$SETPRV();
  38. extern unsigned long LIB$GETJPI(), LIB$SPAWN(), LIB$ATTACH();
  39.  
  40. int FDECL(link, (const char *, const char *));
  41.  
  42. void
  43. setrandom()
  44. {
  45.     (void) Srand((long) time ((time_t *) 0));
  46. }
  47.  
  48. static struct tm *
  49. getlt()
  50. {
  51.     time_t date;
  52.  
  53.     (void) time(&date);
  54.     return(localtime(&date));
  55. }
  56.  
  57. int
  58. getyear()
  59. {
  60.     return(1900 + getlt()->tm_year);
  61. }
  62.  
  63. char *
  64. getdate()
  65. {
  66.     static char datestr[7];
  67.     register struct tm *lt = getlt();
  68.  
  69.     Sprintf(datestr, "%2d%2d%2d",
  70.         lt->tm_year, lt->tm_mon + 1, lt->tm_mday);
  71.     if(datestr[2] == ' ') datestr[2] = '0';
  72.     if(datestr[4] == ' ') datestr[4] = '0';
  73.     return(datestr);
  74. }
  75.  
  76. int
  77. phase_of_the_moon()            /* 0-7, with 0: new, 4: full */
  78. {                    /* moon period: 29.5306 days */
  79.                     /* year: 365.2422 days */
  80.     register struct tm *lt = getlt();
  81.     register int epact, diy, goldn;
  82.  
  83.     diy = lt->tm_yday;
  84.     goldn = (lt->tm_year % 19) + 1;
  85.     epact = (11 * goldn + 18) % 30;
  86.     if ((epact == 25 && goldn > 11) || epact == 24)
  87.         epact++;
  88.  
  89.     return( (((((diy + epact) * 6) + 11) % 177) / 22) & 7 );
  90. }
  91.  
  92. int
  93. night()
  94. {
  95.     register int hour = getlt()->tm_hour;
  96.  
  97.     return(hour < 6 || hour > 21);
  98. }
  99.  
  100. int
  101. midnight()
  102. {
  103.     return(getlt()->tm_hour == 0);
  104. }
  105.  
  106. static struct stat buf, hbuf;
  107.  
  108. void
  109. gethdate(name) char *name; {
  110.     register char *np;
  111.  
  112.     if(stat(name, &hbuf))
  113.         error("Cannot get status of %s.",
  114.             (np = rindex(name, ']')) ? np+1 : name);
  115. }
  116.  
  117. int
  118. uptodate(fd)
  119. int fd;
  120. {
  121.     if(fstat(fd, &buf)) {
  122.         pline("Cannot get status of saved level? ");
  123.         return(0);
  124.     }
  125.     if(buf.st_mtime < hbuf.st_mtime) {
  126.         pline("Saved level is out of date. ");
  127.         return(0);
  128.     }
  129.     return(1);
  130. }
  131.  
  132. static int
  133. veryold(fd)
  134. int fd;
  135. {
  136.     register int i;
  137.     time_t date;
  138.  
  139.     if(fstat(fd, &buf)) return(0);            /* cannot get status */
  140.     if(buf.st_size != sizeof(int)) return(0);    /* not an xlock file */
  141.     (void) time(&date);
  142.     if(date - buf.st_mtime < 3L*24L*60L*60L) {    /* recent */
  143.         int lockedpid;    /* should be the same size as hackpid */
  144.         int status, dummy, code = JPI$_PID;
  145.  
  146.         if(read(fd, (char *)&lockedpid, sizeof(lockedpid)) !=
  147.             sizeof(lockedpid))
  148.             /* strange ... */
  149.             return(0);
  150.           if(!(!((status = LIB$GETJPI(&code, &lockedpid, 0, &dummy)) & 1)
  151.              && status == SS$_NONEXPR))
  152.             return(0);
  153.     }
  154.     (void) close(fd);
  155.     for(i = 1; i <= MAXLEVEL+1; i++) {        /* try to remove all */
  156.         glo(i);
  157.         (void) delete(lock);
  158.     }
  159.     glo(0);
  160.     if(delete(lock)) return(0);            /* cannot remove it */
  161.     return(1);                    /* success! */
  162. }
  163.  
  164. void
  165. getlock()
  166. {
  167.     register int i = 0, fd;
  168.  
  169. #ifdef HARD
  170.     /* idea from rpick%ucqais@uccba.uc.edu
  171.      * prevent automated rerolling of characters
  172.      * test input (fd0) so that tee'ing output to get a screen dump still
  173.      * works
  174.      * also incidentally prevents development of any hack-o-matic programs
  175.      */
  176.     if (isatty(0) <= 0)
  177.         error("You must play from a terminal.");
  178. #endif
  179.  
  180.     (void) fflush(stdout);
  181.  
  182.     /* we ignore QUIT and INT at this point */
  183.     if (link(HLOCK, LLOCK) == -1) {
  184.         register int errnosv = errno;
  185.  
  186.         perror(HLOCK);
  187.         Printf("Cannot link %s to %s\n", LLOCK, HLOCK);
  188.         switch(errnosv) {
  189.         case ENOENT:
  190.             Printf("Perhaps there is no (empty) file %s ?\n", HLOCK);
  191.             break;
  192.         case EACCES:
  193.             Printf("It seems you don't have write permission here.\n");
  194.             break;
  195.         case EEXIST:
  196.             Printf("(Try again or rm %s.)\n", LLOCK);
  197.             break;
  198.         default:
  199.             Printf("I don't know what is wrong.");
  200.         }
  201.         getret();
  202.         error("");
  203.         /*NOTREACHED*/
  204.     }
  205.  
  206.     regularize(lock);
  207.     glo(0);
  208.     if(locknum > 25) locknum = 25;
  209.  
  210.     do {
  211.         if(locknum) lock[0] = 'a' + i++;
  212.  
  213.         if((fd = open(lock, 0)) == -1) {
  214.             if(errno == ENOENT) goto gotlock;    /* no such file */
  215.             perror(lock);
  216.             (void) unlink(LLOCK);
  217.             error("Cannot open %s", lock);
  218.         }
  219.  
  220.         if(veryold(fd))    /* if true, this closes fd and unlinks lock */
  221.             goto gotlock;
  222.         (void) close(fd);
  223.     } while(i < locknum);
  224.  
  225.     (void) unlink(LLOCK);
  226.     error(locknum ? "Too many hacks running now."
  227.               : "There is a game in progress under your name.");
  228. gotlock:
  229.     fd = creat(lock, FCMASK);
  230.     if(unlink(LLOCK) == -1)
  231.         error("Cannot unlink %s.", LLOCK);
  232.     if(fd == -1) {
  233.         error("cannot creat lock file.");
  234.     } else {
  235.         if(write(fd, (char *) &hackpid, sizeof(hackpid))
  236.             != sizeof(hackpid)){
  237.             error("cannot write lock");
  238.         }
  239.         if(close(fd) == -1) {
  240.             error("cannot close lock");
  241.         }
  242.     }
  243. }    
  244.  
  245. void
  246. regularize(s)    /* normalize file name */
  247. register char *s;
  248. {
  249.     register char *lp;
  250.  
  251.     for (lp = s; *lp; lp++)         /* note: '-' becomes '_' */
  252.         if (!(isalpha(*lp) || isdigit(*lp) || *lp == '$'))
  253.             *lp = '_';
  254. }
  255.  
  256. int link(file, new)
  257. const char *file, *new;
  258. {
  259.     unsigned long status;
  260.     struct FAB fab;
  261.     struct NAM nam;
  262.     unsigned short fid[3];
  263.     char esa[NAM$C_MAXRSS];
  264.  
  265.     fab = cc$rms_fab;
  266.     fab.fab$l_fop = FAB$M_OFP;
  267.     fab.fab$l_fna = file;
  268.     fab.fab$b_fns = strlen(file);
  269.     fab.fab$l_nam = &nam;
  270.  
  271.     nam = cc$rms_nam;
  272.     nam.nam$l_esa = esa;
  273.     nam.nam$b_ess = NAM$C_MAXRSS;
  274.  
  275.     if (!((status = SYS$PARSE(&fab)) & 1)
  276.     || !((status = SYS$SEARCH(&fab)) & 1))
  277.     {
  278.     C$$TRANSLATE(status);
  279.     return -1;
  280.     }
  281.  
  282.     fid[0] = nam.nam$w_fid[0];
  283.     fid[1] = nam.nam$w_fid[1];
  284.     fid[2] = nam.nam$w_fid[2];
  285.  
  286.     fab.fab$l_fna = new;
  287.     fab.fab$b_fns = strlen(new);
  288.  
  289.     if (!((status = SYS$PARSE(&fab)) & 1))
  290.     {
  291.     C$$TRANSLATE(status);
  292.     return -1;
  293.     }
  294.  
  295.     nam.nam$w_fid[0] = fid[0];
  296.     nam.nam$w_fid[1] = fid[1];
  297.     nam.nam$w_fid[2] = fid[2];
  298.  
  299.     nam.nam$l_esa = nam.nam$l_name;
  300.     nam.nam$b_esl = nam.nam$b_name + nam.nam$b_type + nam.nam$b_ver;
  301.  
  302.     if (!((status = SYS$ENTER(&fab)) & 1))
  303.     {
  304.     C$$TRANSLATE(status);
  305.     return -1;
  306.     }
  307.  
  308.     return 0;
  309. }
  310.  
  311. #undef unlink
  312. int unlink(file)
  313. const char *file;
  314. {
  315.     int status;
  316.     struct FAB fab = cc$rms_fab;
  317.     struct NAM nam = cc$rms_nam;
  318.     char esa[NAM$C_MAXRSS];
  319.  
  320.     fab.fab$l_fop = FAB$M_DLT;
  321.     fab.fab$l_fna = (char *) file;
  322.     fab.fab$b_fns = strlen(file);
  323.     fab.fab$l_nam = &nam;
  324.     nam.nam$l_esa = esa;
  325.     nam.nam$b_ess = NAM$C_MAXRSS;
  326.  
  327.     if (!((status = SYS$PARSE(&fab)) & 1)
  328.     || !((status = SYS$REMOVE(&fab)) & 1))
  329.     {
  330.     C$$TRANSLATE(status);
  331.     return -1;
  332.     }
  333.  
  334.     return 0;
  335. }
  336.  
  337. #undef creat
  338. int vms_creat(file, mode)
  339. char *file;
  340. unsigned int mode;
  341. {
  342.     if (index(file, ';'))
  343.     (void) delete(file);
  344.     return creat(file, mode);
  345. }
  346.  
  347. #undef getuid
  348. int
  349. vms_getuid()
  350. {
  351.     return (getgid() << 16) | getuid();
  352. }
  353.  
  354. #if defined(CHDIR) || defined(SHELL)
  355. unsigned int oprv[2];
  356.  
  357. void
  358. privoff()
  359. {
  360.     unsigned long prv[2] = { -1, -1 }, code = JPI$_PROCPRIV;
  361.  
  362.     (void) SYS$SETPRV(0, prv, 0, oprv);
  363.     (void) LIB$GETJPI(&code, 0, 0, prv);
  364.     (void) SYS$SETPRV(1, prv, 0, 0);
  365. }
  366.  
  367. void
  368. privon()
  369. {
  370.     (void) SYS$SETPRV(1, oprv, 0, 0);
  371. }
  372. #endif  /*CHDIR || SHELL*/
  373.  
  374. #ifdef SHELL
  375. unsigned long dosh_pid = 0;
  376.  
  377. int
  378. dosh()
  379. {
  380.     int status;
  381.  
  382.     settty((char *) NULL);    /* also calls end_screen() */
  383.     (void) signal(SIGINT,SIG_DFL);
  384.     (void) signal(SIGQUIT,SIG_IGN);
  385.     if (!dosh_pid || !((status = LIB$ATTACH(&dosh_pid)) & 1))
  386.     {
  387. #ifdef CHDIR
  388.         (void) chdir(getenv("PATH"));
  389. #endif
  390.         privoff();
  391.         dosh_pid = 0;
  392.         status = LIB$SPAWN(0, 0, 0, 0, 0, &dosh_pid);
  393.         privon();
  394. #ifdef CHDIR
  395.         chdirx((char *) 0, 0);
  396. #endif
  397.     }
  398.     gettty();
  399.     setftty();
  400.     (void) signal(SIGINT, (SIG_RET_TYPE) done1);
  401. #ifdef WIZARD
  402.     if(wizard) (void) signal(SIGQUIT,SIG_DFL);
  403. #endif
  404.     docrt();
  405.     if (!(status & 1))
  406.         pline("Spawn failed.  Try again.");
  407.     return 0;
  408. }
  409. #endif
  410.